<!DOCTYPE html>

<html>
<head>
<title>UI Components - Composite new Component With Go - QOR5 Document</title>

<meta name='description'>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<base href='/docs/'>

<link href='index.css' rel='stylesheet' type='text/css'>

<script type='text/javascript' defer src='index.js'></script>
</head>

<body>
<div id='app' v-cloak>
<div v-init-context:vars='{hideAside: false}' class='flex h-screen'>
<div class='flex-1 flex flex-col overflow-hidden'>
<div class='flex h-full'>
<aside v-show='!vars.hideAside' id='menuScroller' class='flex flex-col w-80 h-full bg-gray-50 border-r border-gray-200 overflow-y-auto'>
<div class='h-12'><search></search></div>

<ul class='px-0 py-3 mx-0 text-base font-normal list-none text-gray-700'>
<li class='m-0'>
<a href='index.html' id='index.html' onclick='window.storeMenuState("index.html")' class='inline-block px-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Introduction</a>
</li>

<li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Getting Started</li>

<li class='m-0'>
<a href='getting-started/one-minute-quick-start.html' id='getting-started/one-minute-quick-start.html' onclick='window.storeMenuState("getting-started/one-minute-quick-start.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>1 Minute Quick Start</a>
</li>

<li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Building Admin</li>

<li class='m-0'>
<a href='basics/presets-instant-crud.html' id='basics/presets-instant-crud.html' onclick='window.storeMenuState("basics/presets-instant-crud.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>presets, Instant CRUD</a>
</li>

<li class='m-0'>
<a href='basics/listing.html' id='basics/listing.html' onclick='window.storeMenuState("basics/listing.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Listing</a>
</li>

<li class='m-0'>
<a href='basics/listing-customizations.html' id='basics/listing-customizations.html' onclick='window.storeMenuState("basics/listing-customizations.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Listing Customizations</a>
</li>

<li class='m-0'>
<a href='basics/filter.html' id='basics/filter.html' onclick='window.storeMenuState("basics/filter.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Filters</a>
</li>

<li class='m-0'>
<a href='presets-guide/editing-customizations.html' id='presets-guide/editing-customizations.html' onclick='window.storeMenuState("presets-guide/editing-customizations.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Editing</a>
</li>

<li class='m-0'>
<a href='basics/brand.html' id='basics/brand.html' onclick='window.storeMenuState("basics/brand.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Brand</a>
</li>

<li class='m-0'>
<a href='basics/menu.html' id='basics/menu.html' onclick='window.storeMenuState("basics/menu.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Menu</a>
</li>

<li class='m-0'>
<a href='presets-guide/detail-page-for-complex-object.html' id='presets-guide/detail-page-for-complex-object.html' onclick='window.storeMenuState("presets-guide/detail-page-for-complex-object.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Detailing</a>
</li>

<li class='m-0'>
<a href='basics/layout.html' id='basics/layout.html' onclick='window.storeMenuState("basics/layout.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Layout</a>
</li>

<li class='m-0'>
<a href='basics/login.html' id='basics/login.html' onclick='window.storeMenuState("basics/login.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Login</a>
</li>

<li class='m-0'>
<a href='presets-guide/permissions.html' id='presets-guide/permissions.html' onclick='window.storeMenuState("presets-guide/permissions.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Permissions</a>
</li>

<li class='m-0'>
<a href='presets-guide/role.html' id='presets-guide/role.html' onclick='window.storeMenuState("presets-guide/role.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Role</a>
</li>

<li class='m-0'>
<a href='basics/shortcut.html' id='basics/shortcut.html' onclick='window.storeMenuState("basics/shortcut.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Keyboard Shortcut</a>
</li>

<li class='m-0'>
<a href='basics/confirm-dialog.html' id='basics/confirm-dialog.html' onclick='window.storeMenuState("basics/confirm-dialog.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Confirm Dialog</a>
</li>

<li class='m-0'>
<a href='slug.html' id='slug.html' onclick='window.storeMenuState("slug.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Slug</a>
</li>

<li class='m-0'>
<a href='seo.html' id='seo.html' onclick='window.storeMenuState("seo.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>SEO</a>
</li>

<li class='m-0'>
<a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
</li>

<li class='m-0'>
<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
</li>

<li class='m-0'>
<a href='basics/publish.html' id='basics/publish.html' onclick='window.storeMenuState("basics/publish.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Publish</a>
</li>

<li class='m-0'>
<a href='basics/i18n.html' id='basics/i18n.html' onclick='window.storeMenuState("basics/i18n.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Internationalization</a>
</li>

<li class='m-0'>
<a href='basics/l10n.html' id='basics/l10n.html' onclick='window.storeMenuState("basics/l10n.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Localization</a>
</li>

<li class='m-0'>
<a href='basics/redirection.html' id='basics/redirection.html' onclick='window.storeMenuState("basics/redirection.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Redirection</a>
</li>

<li class='m-0'>
<a href='basics/custom-page.html' id='basics/custom-page.html' onclick='window.storeMenuState("basics/custom-page.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Custom Pages</a>
</li>

<li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>

<li class='m-0'>
<a href='advanced-functions/the-go-html-builder.html' id='advanced-functions/the-go-html-builder.html' onclick='window.storeMenuState("advanced-functions/the-go-html-builder.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>The Go HTML builder</a>
</li>

<li class='m-0'>
<a href='basics/page-func-and-event-func.html' id='basics/page-func-and-event-func.html' onclick='window.storeMenuState("basics/page-func-and-event-func.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Page Func and Event Func</a>
</li>

<li class='m-0'>
<a href='basics/layout-function-and-page-injector.html' id='basics/layout-function-and-page-injector.html' onclick='window.storeMenuState("basics/layout-function-and-page-injector.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Layout Function and Page Injector</a>
</li>

<li class='m-0'>
<a href='vuetify-components/lazy-portals.html' id='vuetify-components/lazy-portals.html' onclick='window.storeMenuState("vuetify-components/lazy-portals.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Lazy Portals</a>
</li>

<li class='m-0'>
<a href='basics/switch-pages-with-push-state.html' id='basics/switch-pages-with-push-state.html' onclick='window.storeMenuState("basics/switch-pages-with-push-state.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Switch Pages with Push State</a>
</li>

<li class='m-0'>
<a href='basics/reload-page-with-a-flash.html' id='basics/reload-page-with-a-flash.html' onclick='window.storeMenuState("basics/reload-page-with-a-flash.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Reload Page with a Flash</a>
</li>

<li class='m-0'>
<a href='basics/partial-refresh-with-portal.html' id='basics/partial-refresh-with-portal.html' onclick='window.storeMenuState("basics/partial-refresh-with-portal.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Partial Refresh with Portal</a>
</li>

<li class='m-0'>
<a href='basics/manipulate-page-url-in-event-func.html' id='basics/manipulate-page-url-in-event-func.html' onclick='window.storeMenuState("basics/manipulate-page-url-in-event-func.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Manipulate Page URL in Event Func</a>
</li>

<li class='m-0'>
<a href='basics/summary-of-event-response.html' id='basics/summary-of-event-response.html' onclick='window.storeMenuState("basics/summary-of-event-response.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Summary of Event Response</a>
</li>

<li class='m-0'>
<a href='basics/web-scope.html' id='basics/web-scope.html' onclick='window.storeMenuState("basics/web-scope.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>web.Scope</a>
</li>

<li class='m-0'>
<a href='basics/event-handling.html' id='basics/event-handling.html' onclick='window.storeMenuState("basics/event-handling.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Event Handling</a>
</li>

<li class='m-0'>
<a href='basics/form-handling.html' id='basics/form-handling.html' onclick='window.storeMenuState("basics/form-handling.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Form Handling</a>
</li>

<li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>UI Components</li>

<li class='m-0'>
<a href='vuetify-components/basic-inputs.html' id='vuetify-components/basic-inputs.html' onclick='window.storeMenuState("vuetify-components/basic-inputs.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Basic Inputs</a>
</li>

<li class='m-0'>
<a href='vuetify-components/a-taste-of-using-vuetify-in-go.html' id='vuetify-components/a-taste-of-using-vuetify-in-go.html' onclick='window.storeMenuState("vuetify-components/a-taste-of-using-vuetify-in-go.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>A Taste of using Vuetify in Go</a>
</li>

<li class='m-0'>
<a href='vuetify-components/linkage-select.html' id='vuetify-components/linkage-select.html' onclick='window.storeMenuState("vuetify-components/linkage-select.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Linkage Select</a>
</li>

<li class='m-0'>
<a href='components-guide/composite-new-component-with-go.html' id='components-guide/composite-new-component-with-go.html' onclick='window.storeMenuState("components-guide/composite-new-component-with-go.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-blue-500'>Composite new Component With Go</a>
</li>

<li class='m-0'>
<a href='components-guide/integrate-a-heavy-vue-component.html' id='components-guide/integrate-a-heavy-vue-component.html' onclick='window.storeMenuState("components-guide/integrate-a-heavy-vue-component.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Integrate a heavy Vue Component</a>
</li>

<li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Appendix</li>

<li class='m-0'>
<a href='appendix/all-demo-examples.html' id='appendix/all-demo-examples.html' onclick='window.storeMenuState("appendix/all-demo-examples.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>All Demo Examples</a>
</li>
</ul>
</aside>

<main class='flex flex-col w-full bg-white overflow-x-hidden overflow-y-auto'>
<div id='docContentBox' class='flex flex-row w-full'>
<div class='flex flex-grow flex-col w-2/3'>
<div class='flex flex-row'>
<button @click='vars.hideAside = !vars.hideAside' class='w-12 h-12 p-4'>
<div class='w-4 h-4 fill-current text-gray-300'>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 2 12 L 2 11 L 14 11 L 14 12 Z M 2 8.5 L 2 7.5 L 14 7.5 L 14 8.5 Z M 2 5 L 2 4 L 14 4 L 14 5 Z M 2 5 "/>
</g>
</svg>
</div>
</button>
</div>

<div id='docMainBox' class='px-16 pb-12 pt-4 overflow-auto'>
<h1 class='mb-8'>Composite new Component With Go</h1>

<div class='border-t'><p>Any Go function that returns an <code>htmlgo.HTMLComponent</code> is a component,
Any Go struct that implements <code>MarshalHTML(ctx context.Context) ([]byte, error)</code> function is an component.
They can be composite into a new component very easy.</p>

<p>This example is ported from <a href="https://getbootstrap.com/docs/4.3/components/navbar/" rel="nofollow">Bootstrap4 Navbar</a>:</p>

<highlightjs :language='"go"' :code='"import (\n\t\"fmt\"\n\n\t\"github.com/qor5/web/v3\"\n\t. \"github.com/theplant/htmlgo\"\n)\n\nfunc Navbar(title string, activeIndex int, items ...HTMLComponent) HTMLComponent {\n\tul := Ul().Class(\"navbar-nav mr-auto\")\n\n\tfor i, item := range items {\n\t\tul.AppendChildren(\n\t\t\tLi(\n\t\t\t\titem,\n\t\t\t).Class(\"nav-item\").ClassIf(\"active\", activeIndex == i),\n\t\t)\n\t}\n\n\treturn Nav(\n\t\tA(Text(title)).Class(\"navbar-brand\").\n\t\t\tHref(\"#\"),\n\n\t\tButton(\"\").Class(\"navbar-toggler\").\n\t\t\tType(\"button\").\n\t\t\tAttr(\"data-toggle\", \"collapse\").\n\t\t\tAttr(\"data-target\", \"#navbarNav\").\n\t\t\tAttr(\"aria-controls\", \"navbarNav\").\n\t\t\tAttr(\"aria-expanded\", \"false\").\n\t\t\tAttr(\"aria-label\", \"Toggle navigation\").\n\t\t\tChildren(\n\t\t\t\tSpan(\"\").Class(\"navbar-toggler-icon\"),\n\t\t\t),\n\n\t\tDiv(\n\t\t\tul,\n\t\t\tForm(\n\t\t\t\tInput(\"\").Class(\"form-control mr-sm-2\").\n\t\t\t\t\tType(\"search\").\n\t\t\t\t\tPlaceholder(\"Search\").\n\t\t\t\t\tAttr(\"aria-label\", \"Search\"),\n\t\t\t\tButton(\"Search\").Class(\"btn btn-outline-light my-2 my-sm-0\").\n\t\t\t\t\tType(\"submit\"),\n\t\t\t).Class(\"form-inline my-2 my-lg-0\"),\n\t\t).Class(\"collapse navbar-collapse\").\n\t\t\tId(\"navbarNav\"),\n\t).Class(\"navbar navbar-expand-lg navbar-dark bg-primary\")\n}\n\ntype CarouselItem struct {\n\tImageSrc string\n\tImageAlt string\n}\n\nfunc Carousel(carouselId string, activeIndex int, items []*CarouselItem) HTMLComponent {\n\tindicators := Ol().Class(\"carousel-indicators\")\n\tcarouselInners := Div().Class(\"carousel-inner\")\n\n\tfor i, item := range items {\n\t\tindicators.AppendChildren(\n\t\t\tLi().Attr(\"data-target\", \"#\"+carouselId).\n\t\t\t\tAttr(\"data-slide-to\", fmt.Sprint(i)).\n\t\t\t\tClassIf(\"active\", activeIndex == i),\n\t\t)\n\n\t\tcarouselInners.AppendChildren(\n\t\t\tDiv(\n\t\t\t\tfakeImage(item.ImageAlt),\n\t\t\t).Class(\"carousel-item\").ClassIf(\"active\", activeIndex == i).Style(\"font-size: 3.5rem;\"),\n\t\t)\n\t}\n\n\treturn Div(\n\t\tindicators,\n\t\tcarouselInners,\n\t\tA(\n\t\t\tSpan(\"\").Class(\"carousel-control-prev-icon\").\n\t\t\t\tAttr(\"aria-hidden\", \"true\"),\n\t\t\tSpan(\"Previous\").Class(\"sr-only\"),\n\t\t).Class(\"carousel-control-prev\").\n\t\t\tHref(\"#\"+carouselId).\n\t\t\tRole(\"button\").\n\t\t\tAttr(\"data-slide\", \"prev\"),\n\t\tA(\n\t\t\tSpan(\"\").Class(\"carousel-control-next-icon\").\n\t\t\t\tAttr(\"aria-hidden\", \"true\"),\n\t\t\tSpan(\"Next\").Class(\"sr-only\"),\n\t\t).Class(\"carousel-control-next\").\n\t\t\tHref(\"#\"+carouselId).\n\t\t\tRole(\"button\").\n\t\t\tAttr(\"data-slide\", \"next\"),\n\t).Id(carouselId).\n\t\tClass(\"carousel slide\").\n\t\tAttr(\"data-ride\", \"carousel\")\n}\n\nfunc CompositeComponentSample1Page(ctx *web.EventContext) (pr web.PageResponse, err error) {\n\tpr.Body = Div(\n\t\tNavbar(\n\t\t\t\"Hello\",\n\t\t\t1,\n\n\t\t\tA(\n\t\t\t\tText(\"Home\"),\n\t\t\t).Class(\"nav-link\").\n\t\t\t\tHref(\"#\"),\n\n\t\t\tA(\n\t\t\t\tText(\"Features\"),\n\t\t\t).Class(\"nav-link\").\n\t\t\t\tHref(\"#\"),\n\n\t\t\tA(\n\t\t\t\tText(\"Pricing\"),\n\t\t\t).Class(\"nav-link\").\n\t\t\t\tHref(\"#\"),\n\n\t\t\tA(\n\t\t\t\tText(\"Disabled\"),\n\t\t\t).Class(\"nav-link disabled\").\n\t\t\t\tHref(\"#\").\n\t\t\t\tTabIndex(-1).\n\t\t\t\tAttr(\"aria-disabled\", \"true\"),\n\t\t),\n\n\t\tDiv(\n\t\t\tDiv(\n\t\t\t\tDiv(\n\t\t\t\t\tCarousel(\"hello1\", 1, []*CarouselItem{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tImageAlt: \"First slide\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tImageAlt: \"Second slide\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tImageAlt: \"Third slide\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t).Class(\"col-12 py-md-3 pl-md-3\"),\n\t\t\t).Class(\"row\"),\n\t\t).Class(\"container-fluid\"),\n\t)\n\treturn\n}\n\nvar CompositeComponentSample1PagePB = web.Page(CompositeComponentSample1Page)\n\nvar CompositeComponentSample1PagePath = URLPathByFunc(CompositeComponentSample1Page)\n"'></highlightjs>

<div>
<div class='demo'>
<a href='/examples/composite-component-sample-1-page' target='_blank'>Check the demo</a>
 | 
<a href='https://github.com/qor5/admin/tree/main/docs/docsrc/../../../../../go/pkg/mod/github.com/qor5/web/v3@v3.0.12-0.20250225073451-8e876be98c21/examples/composite-components.go#L3-L153' target='_blank'>Source on GitHub</a>
</div>
</div>
<p>You can see from the example, We have created <code>Navbar</code> and <code>Carousel</code> components by
simply create Go func that returns <code>htmlgo.HTMLComponent</code>.
It is easy to pass in components as parameter, and wrap components.
By utilizing the power of Go language, Any component can be abstracted and reused with enough parameters.</p>

<p>The <code>Navbar</code> is a responsive navigation header, Resizing your window, the nav bar will react to device window size and change to nav bar popup and hide search form.</p>

<p>For this <code>Navbar</code> component to work, I have to import Bootstrap assets in this new layout function:</p>

<highlightjs :language='"go"' :code='"func demoBootstrapLayout(in web.PageFunc) (out web.PageFunc) {\n\treturn func(ctx *web.EventContext) (pr web.PageResponse, err error) {\n\n\t\tctx.Injector.HeadHTML(`\n\u003clink rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\"\u003e\n\u003cscript src=&#39;/assets/vue.js&#39;\u003e\u003c/script\u003e\n\t\t`)\n\n\t\tctx.Injector.TailHTML(`\n\u003cscript src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js\" integrity=\"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js\" integrity=\"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n\u003cscript src=&#39;/assets/main.js&#39;\u003e\u003c/script\u003e\n\n`)\n\t\tctx.Injector.HeadHTML(`\n\t\t\u003cstyle\u003e\n\t\t\t[v-cloak] {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\u003c/style\u003e\n\t\t`)\n\n\t\tvar innerPr web.PageResponse\n\t\tinnerPr, err = in(ctx)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tpr.Body = innerPr.Body\n\n\t\treturn\n\t}\n}\n"'></highlightjs>
<p>You can utilize the command line tool <a href="https://github.com/sunfmin/html2go" rel="nofollow">html2go</a> to convert existing html code to htmlgo code.
By writing html in Go you get:</p>

<ul>
<li>The static type checking</li>
<li>Abstract out easily to different functions</li>
<li>Easier refactor with IDE like GoLand</li>
<li>Loop and variable replacing is just like in Go</li>
<li>Invoke helper functions is just like in Go</li>
<li>Almost as readable as normal HTML</li>
<li>Not possible to have html tag not closed, Or not matched.</li>
</ul>

<p>Once you have these, Why generate html in any interpreted template language!</p>
</div>
</div>
</div>

<div class='font-medium text-base hidden xl:block text-gray-600 pt-4'>
<div class='sticky top-4 w-52'>On This Page<toc></toc></div>
</div>
</div>
<search-result></search-result></main>
</div>
</div>
</div>
</div>
</body>
</html>
